package cn.wjh.business.service.impl;

import cn.wjh.business.domain.Comment;
import cn.wjh.business.mapper.CommentMapper;
import cn.wjh.business.mapper.CompetitionMapper;
import cn.wjh.business.mapper.WorksMapper;
import cn.wjh.business.service.ICommentService;
import cn.wjh.business.utils.IpAddressParser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 评论Service业务层处理
 *
 * @author jiraWu
 * @date 2023-10-26
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {
	@Resource
	private CommentMapper commentMapper;

	@Resource
	private CompetitionMapper competitionMapper;
	@Resource
	private WorksMapper worksMapper;

	/**
	 * mapper映射关系
	 */
	private Map<String, BaseMapper<?>> mapperMap;

	@PostConstruct
	public void init() {
		mapperMap = new HashMap<>();
		mapperMap.put("competition", competitionMapper);
		mapperMap.put("works", worksMapper);
	}

	/**
	 * 查询评论
	 *
	 * @param commentId 评论主键
	 * @return 评论
	 */
	@Override
	public Comment selectCommentByCommentId(Long commentId) {
		return commentMapper.selectCommentByCommentId(commentId);
	}

	/**
	 * 查询评论列表
	 *
	 * @param comment 评论
	 * @return 评论
	 */
	@Override
	public List<Comment> selectCommentList(Comment comment) {
		return commentMapper.selectCommentList(comment);
	}

	/**
	 * 新增评论
	 *
	 * @param comment 评论
	 * @return 结果
	 */
	@Override
	public int insertComment(Comment comment) {
		comment.setCreateTime(DateUtils.getNowDate());//评论时间
		comment.setCreateBy(SecurityUtils.getUsername());//评论人

//		设置提交人信息
		comment.setUserId(SecurityUtils.getUserId());

		//设置接收的用户id
		comment.setReceiveId(getReceiverUserId(comment.getType(), comment.getDataId()));

		String ip = IpUtils.getIpAddr();
//		设置ip地址
		comment.setIp(ip);

//		设置ip所属地
		comment.setAddr(IpAddressParser.parse(ip));

		return commentMapper.insertComment(comment);
	}

	/**
	 * 修改评论
	 *
	 * @param comment 评论
	 * @return 结果
	 */
	@Override
	public int updateComment(Comment comment) {
		comment.setUpdateTime(DateUtils.getNowDate());
		comment.setUpdateBy(SecurityUtils.getUsername());
		return commentMapper.updateComment(comment);
	}

	/**
	 * 批量删除评论
	 *
	 * @param commentIds 需要删除的评论主键
	 * @return 结果
	 */
	@Override
	public int deleteCommentByCommentIds(Long[] commentIds) {
		return commentMapper.deleteCommentByCommentIds(commentIds);
	}

	/**
	 * 删除评论信息
	 *
	 * @param commentId 评论主键
	 * @return 结果
	 */
	@Override
	public int deleteCommentByCommentId(Long commentId) {
		return commentMapper.deleteCommentByCommentId(commentId);
	}

	/**
	 * 发送评论(二级)
	 */
	@Override
	public boolean sendReply(Comment comment) {
		comment.setCommentId(null);
		Long parentId = comment.getParentId();
		if (StringUtils.isNull(parentId))
			throw new ServiceException("parentId不能为空", HttpStatus.ERROR);
		//查询父级信息
		Comment parent = commentMapper.selectById(parentId);
		if (parent == null)
			throw new ServiceException("回复失败", HttpStatus.ERROR);

		//设置父节点和root节点的信息
		if (StringUtils.isNull(parent.getRootId()))
			comment.setRootId(parent.getCommentId()); //不存在rootId 自己就是根节点
		else
			comment.setRootId(parent.getRootId()); //存在rootId 同步设置rootId

		comment.setType(parent.getType()); //父节点的类型
		comment.setDataId(parent.getDataId()); //关联的dataId

		String ip = IpUtils.getIpAddr();
//		设置ip地址
		comment.setIp(ip);

//		设置ip所属地
		comment.setAddr(IpAddressParser.parse(ip));


		LoginUser loginUser = SecurityUtils.getLoginUser();

		comment.setUserId(loginUser.getUserId()); //当前的用户id 发送人
		comment.setReceiveId(parent.getUserId()); //父节点的发送人 就是回复的接收人
		comment.setCreateBy(loginUser.getUsername());
		comment.setCreateTime(DateUtils.getNowDate());
		return super.save(comment);
	}

	/**
	 * 获取一级评论
	 *
	 * @param comment
	 * @return
	 */
	@Override
	public List<Comment> selectFirstCommentList(Comment comment) {
		comment.setStatus(true);
		List<Comment> comments = commentMapper.selectFirstCommentList(comment);
		comments.forEach(c -> {
			Long count = commentMapper.selectChildCountByRootId(c.getCommentId());
			c.setSubTotal(count);
		});
		return comments;
	}


	@Override
	public List<Comment> selectChildByRootId(Long commentId) {
		return commentMapper.selectChildByRootId(commentId);
	}

	/**
	 * 获取我的评论
	 *
	 * @param comment
	 * @return
	 */
	@Override
	public List<Comment> myComment(Comment comment) {
		comment.setUserId(SecurityUtils.getUserId());
		return this.selectCommentList(comment);
	}

	@Override
	public boolean readComment(List<Long> commentIds) {
		LambdaQueryWrapper<Comment> updateWrapper = new QueryWrapper<Comment>().lambda()
				.eq(Comment::getReceiveId, SecurityUtils.getUserId())
				.in(Comment::getCommentId, commentIds);
		Comment comment = new Comment();
		comment.setReadStatus(true);
		return super.update(comment, updateWrapper);
	}

	@Override
	public Map<String, Long> readAndNotReadCount(Comment comment) {
		List<Comment> comments = this.commentMy(comment);
		List<Comment> readCommentList = comments.stream().filter(Comment::getReadStatus).collect(Collectors.toList());
		Map<String, Long> map = new HashMap<>();
		if (comments.isEmpty() && readCommentList.isEmpty()) {
			map.put("read", 0L);
			map.put("notRead", 0L);
		} else {
			map.put("read", (long) readCommentList.size());
			map.put("notRead", (long) (comments.size() - readCommentList.size()));
		}
		return map;
	}

	@Override
	public List<Comment> commentMy(Comment comment) {
		comment.setStatus(true);//获取正常状态的评论
		comment.setReceiveId(SecurityUtils.getUserId());
		return this.selectCommentList(comment);
	}

	public Long getReceiverUserId(String type, Long dataId) {
		//获取对应的mapper
		BaseMapper<?> mapper = mapperMap.get(type);
		if (mapper == null) throw new ServiceException("回复类型错误", HttpStatus.ERROR);
		//根据id查询
		Object entity = mapper.selectById(dataId);
		if (entity == null)
			throw new ServiceException("记录不存在", HttpStatus.ERROR);
		//获取userId
		Class<?> entityClass = entity.getClass();
		try {
			Field userIdField = entityClass.getDeclaredField("userId");
			userIdField.setAccessible(true);
			return (Long) userIdField.get(entity);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
